package com.googlecode.bip.entity.impl;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import com.googlecode.bip.entity.IUserValue;

/**
 * Default implementation of {@link IUserValue}
 */
public class UserValue
    implements Serializable, IUserValue
{
    private static final long serialVersionUID = 3L;

    private int         iduser;     //key
    private int         idquestion; //key
    private Timestamp   userdate;   //key

    /** if null value does not exist in database */
    private Integer uservalue;

    /** Optional - could be null */
    private String usercomment;

    private boolean isPrivate;

    /**
     * Create a NOT initialized UserValue
     */
    // Constructor must be public
    public UserValue()
    {
        //empty
    }

    /**
     * Create a initialized UserValue with keys
     *
     * @param iduser
     * @param idquestion
     * @param userdate
     *
     * @throws NullPointerException if userdate is null
     */
    public UserValue(
            final int       iduser,
            final int       idquestion,
            final Timestamp userdate
            )
    {
        this.iduser     = iduser;
        this.idquestion = idquestion;

        if( userdate == null ) {
            throw new NullPointerException();
            }

        this.userdate = EntityHelper.getNormalizedTimestamp( userdate );
    }

    /**
     * Create a shadow copy of giving UserValue
     *
     * @param o UserValue to clone
     */
    public UserValue( final UserValue o )
    {
        this.iduser         = o.iduser;
        this.idquestion     = o.idquestion;
        this.userdate       = o.userdate;
        this.uservalue      = o.uservalue;
        this.usercomment    = o.usercomment;
        this.isPrivate      = o.isPrivate;
    }

    public static IUserValue newInstance( final ResultSet rSet ) throws SQLException
    {
        return new UserValue().set( rSet );
    }

    /**
     *
     * @param rSet
     * @return
     * @throws SQLException
     */
    public IUserValue set( final ResultSet rSet ) throws SQLException
    {
        // from uservalues
        iduser      = rSet.getInt( "iduser" );
        idquestion  = rSet.getInt( "idquestion" );
        userdate    = rSet.getTimestamp( "userdate" );
        uservalue   = rSet.getInt( "uservalue" );
        isPrivate   = rSet.getBoolean( "isprivate" );

        // from uservaluecomments
        usercomment = rSet.getString( "usercomment" );

        return this;
    }

    @Override
    public int getIdUser()
    {
        return iduser;
    }

    // REQUIRED FOR JSON
    @Override
    public void setIdUser(int iduser) {
        this.iduser = iduser;
    }

    @Override
    public int getIdQuestion()
    {
        return idquestion;
    }

    // REQUIRED FOR JSON
    @Override
    public void setIdQuestion(int idquestion) {
        this.idquestion = idquestion;
    }

    @Override
    public Timestamp getUserDate()
    {
        return userdate;
    }

    // REQUIRED FOR JSON
    @Override
    public void setUserDate( final Timestamp userdate )
    {
        if( userdate == null ) {
            throw new NullPointerException();
            }
        this.userdate = EntityHelper.getNormalizedTimestamp( userdate );
    }

    @Override
    public Integer getUserValue()
    {
        return uservalue;
    }

    @Override
    // MUST TAKE AN integer as args or JSON will have problems
    public void setUserValue( final Integer uservalue )
    {
        if( uservalue == null ) {
            throw new NullPointerException();
            }

        // check value from Question min/max ???
        this.uservalue =  uservalue ;
    }

    @Override
    public String getUserComment()
    {
        return usercomment;
    }

    @Override
    public void setUserComment( String usercomment )
    {
        if( usercomment != null ) {
            usercomment = usercomment.trim();
            }

        this.usercomment = usercomment;
    }

    @Override
    public boolean isPrivate()
    {
        return this.isPrivate;
    }

    @Override
    public void setPrivate( final boolean isPrivate )
    {
        this.isPrivate = isPrivate;
    }

    @Override
    public String toString()
    {
        StringBuilder builder = new StringBuilder();

        builder.append( "UserValue [iduser=" ).append( iduser )
               .append( ", idquestion=" ).append( idquestion )
               .append( ", userdate=" ).append( userdate )
               .append( ", uservalue=" ).append( uservalue )
               .append( ", usercomment=" ).append( usercomment )
               .append( "]" );

        return builder.toString();
    }

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + idquestion;
        result = prime * result + iduser;
        result = prime * result
                + ((usercomment == null) ? 0 : usercomment.hashCode());
        result = prime * result
                + ((userdate == null) ? 0 : userdate.hashCode());
        result = prime * result
                + ((uservalue == null) ? 0 : uservalue.hashCode());
        return result;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals( Object obj )
    {
        if( this == obj ) {
            return true;
        }
        if( obj == null ) {
            return false;
        }
        if( getClass() != obj.getClass() ) {
            return false;
        }
        UserValue other = (UserValue)obj;
        if( idquestion != other.idquestion ) {
            return false;
        }
        if( iduser != other.iduser ) {
            return false;
        }
        if( usercomment == null ) {
            if( other.usercomment != null ) {
                return false;
            }
        } else if( !usercomment.equals( other.usercomment ) ) {
            return false;
        }
        if( userdate == null ) {
            if( other.userdate != null ) {
                return false;
            }
        } else if( !userdate.equals( other.userdate ) ) {
            return false;
        }
        if( uservalue == null ) {
            if( other.uservalue != null ) {
                return false;
            }
        } else if( !uservalue.equals( other.uservalue ) ) {
            return false;
        }
        return true;
    }

}
